package mx.tarhimurhu.amoxcalli.util;


import mx.tarhimurhu.amoxcalli.*;
import mx.tarhimurhu.amoxcalli.ui.swing.AboutUI;
import mx.tarhimurhu.amoxcalli.ui.swing.CentralConsoleUI;
import mx.tarhimurhu.amoxcalli.ui.swing.EntryUI;
import mx.tarhimurhu.amoxcalli.ui.swing.HelpUI;
import mx.tarhimurhu.amoxcalli.ui.swing.ProjectUI;
import mx.tarhimurhu.amoxcalli.ui.swing.SettingsUI;
import mx.tarhimurhu.amoxcalli.util.DBConnectionHelper;

import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.WindowConstants;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

// Singleton
public class Controller 
{
	private static Controller controller = null;
	private ArrayList<Project> projects;
	private CentralConsoleUI view;
	
	private Controller()
	{
		try 
		{
			projects = readProjects();
		} 
		catch (Exception e) 
		{
			e.printStackTrace();
		}
	}
	
	
	
	public static Controller getInstance()
	{
		if(controller == null)
			controller = new Controller();
		
		return controller;
	}
	
	
	
	public void go()
	{
		view = new CentralConsoleUI();
		view.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		view.setLocationRelativeTo(null); // Open window in center of screen
		view.setVisible(true);
		
		view.populateContent(projects);
	}
	
	
	
	public boolean addProject(String newProjectName) throws Exception
	{
		boolean projectExist = projectExist(newProjectName);
		
		// If project does not exist, add the newProject to ArrayList projects
		if(!projectExist)
		{
			projects.add(new Project(newProjectName));
			update();
		}
		
		return projectExist;
	}
	
	
	
	public boolean removeProject(String removeProjectName) throws Exception
	{
		boolean projectExist = projectExist(removeProjectName);
		
		if(projectExist)
		{
			projects.remove(getProjectIndex(removeProjectName));
			update();
		}
			
		return true;
	}
	
	
	
	public boolean projectExist(String newProjectName)
	{
		boolean projectExist = false;
		
		if(projects != null || !projects.isEmpty())
		{
			for(Project p : projects)
			{
				if(p.getProjectName().equals(newProjectName))
				{
					projectExist = true;
					break;
				}
				else
				{
					projectExist = false;
				}
			}
		}
		
		return projectExist;
	}
	
	
	// Returns the index of the project by providing the project name
	public int getProjectIndex(String projectName)
	{
		int projectIndex = -1;
		
		if(projects != null || !projects.isEmpty())
		{
			for(Project p : projects)
			{
				if(p.getProjectName().equals(projectName))
				{
					projectIndex = projects.indexOf(p);
					return projectIndex;
				}
			}
		}
		
		return projectIndex;
	}
	
	
	// Updates view on central console
	public void update() throws Exception
	{
		view.populateContent(projects);
		writeProjects();
	}
	
	
	public ArrayList<Project> getProjects()
	{
		return projects;
	}
	
	
	private void writeProjects() throws Exception
	{
		DBConnectionHelper.write(projects);
	}
	
	
	
	private ArrayList<Project> readProjects() throws Exception
	{
		return DBConnectionHelper.read();
	}
	
	
	
	/***********************************************************
	 *AddMenuHandler listens to events from the Add JMenuItems.*
	 ***********************************************************/
	public class AddMenuHandler implements ActionListener
	{			
		@Override
		public void actionPerformed(ActionEvent e) 
		{
			JMenuItem menuItem = (JMenuItem) e.getSource();
			
			if(menuItem.getText().equals("New Entry"))
			{			
				// Show new entry window
				EntryUI newEntry = new EntryUI(view, "New Entry");
				newEntry.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
				newEntry.setLocationRelativeTo(view); // Instance of CentralConsoleUI to center Add window
				newEntry.setVisible(true);
			}
			else if(menuItem.getText().equals("New Project"))
			{
				// Show new project window
				ProjectUI newProject = new ProjectUI(view, "New Project");
				newProject.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
				newProject.setLocationRelativeTo(view);
				newProject.setVisible(true);
			}	
		}
		
	}

	
	
	/********************************************************************
	 *AddProjectHandler listens to events from the Add ProjectUI Dialog.*
	 ********************************************************************/
	public class AddProjectHandler implements ActionListener
	{
		private ProjectUI dialog; // Need this object to interact with input from ProjectUI
		
		public AddProjectHandler(ProjectUI d)
		{ 
			dialog = d; 
		}
		
		@Override
		public void actionPerformed(ActionEvent e) 
		{
			boolean projectExist = true;
			
			try 
			{
				if(!dialog.getProjectName().equals(""))
				{
					// Add project and return boolean if project exist
					projectExist = controller.addProject(dialog.getProjectName());
				}
				
			} 
			catch (Exception e1) 
			{
				e1.printStackTrace();
			}
			finally
			{
				if(!projectExist)
				{
					dialog.dispose();
				}
				else
				{
					JOptionPane.showMessageDialog(null, "Project already exist or you did not enter a valid project name.");
					
					dialog.resetTextField();
				}
			}

		}
	}

	
	
	/****************************************************************
	 *AddEntryHandler listens to events from the Add EntryUI Dialog.*
	 ****************************************************************/
	public class AddEntryHandler implements ActionListener
	{
		private EntryUI dialog; 
		
		public AddEntryHandler(EntryUI d)
		{ 
			dialog = d; 
		}
		
		@Override
		public void actionPerformed(ActionEvent e) 
		{
			int selectedProjectIndex = view.getProjectList().getSelectedIndex();
			// TEST
			System.out.println("Project Index = " + selectedProjectIndex);
			
			Entry newEntry = new Article(new Author[]{new Author(dialog.getAuthorFirstName(), dialog.getAuthorMiddleName(), dialog.getAuthorLastName())});
			
			
			//Get Project to which the Entry will be added too.
			Project selectedProject = projects.get(selectedProjectIndex);
			// TEST
			System.out.println("Project Name = " + selectedProject.getProjectName());
			
		
			//Then add entry to project
			selectedProject.addEntry(newEntry);
			
			//Finally replace old project with new project and update list
			projects.set(selectedProjectIndex, selectedProject);
			try 
			{
				update();
			} 
			catch (Exception e1) 
			{
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
	}

	
	
	
	/*******************************************************************
	 *ExportHandler listens to events from the Export JMenuItems.      *
	 *******************************************************************/
	public class ExportHandler implements ActionListener
	{		
		@Override
		public void actionPerformed(ActionEvent e) 
		{
			JMenuItem menuItem = (JMenuItem) e.getSource();
			
			if(menuItem.getText().equals("Bibliography"))
			{
				// Show Bibliography Options Window
			}
			else if(menuItem.getText().equals("Annotated Bibliography"))
			{
				// Show Annotated Bibliography Options Window 
			}	
		}
		
	}
	
	
	
	/****************************************************************
	 *RemoveHandler listens to events from the Remove JMenuItems.   *
	 ****************************************************************/
	public class RemoveHandler implements ActionListener
	{
		@Override
		public void actionPerformed(ActionEvent e) 
		{
			JMenuItem menuItem = (JMenuItem) e.getSource();
			
			/**************Remove Project*****************/
			if(menuItem.getText().equals("Remove Project"))
			{
				if(view.getProjectList().isSelectionEmpty()) // If no selection has been made
				{
					JOptionPane.showMessageDialog(null, "You must select a project to remove.");
				}
				else
				{
					int selection = JOptionPane.showConfirmDialog(null, "Are you sure you would like to permanently delete project " 
							+ view.getProjectList().getSelectedValue() + "? ", "Remove Project", JOptionPane.YES_NO_OPTION);

					// Remove item from list and update DB
					if(selection == JOptionPane.YES_OPTION)
					{
						String projectName = view.getProjectList().getSelectedValue().toString();
						try 
						{	
							controller.removeProject(projectName);
						} 
						catch (Exception e1) 
						{
							e1.printStackTrace();
						}
					}
				}
			}
			
			/**************Remove Entry*****************/
			else if(menuItem.getText().equals("Remove Entry"))
			{
			
			}	
		}

	}
	
	
	
	/*************************************************************
	 *ToolsHandlerlistens to events from the Add JMenuItems.*
	 ************************************************************/
	public class ToolsHandler implements ActionListener
	{			
		@Override
		public void actionPerformed(ActionEvent e) 
		{
			JMenuItem menuItem = (JMenuItem) e.getSource();
			
			if(menuItem.getText().equals("Settings"))
			{
				// Show Settings Window
				SettingsUI settings = new SettingsUI(view);
				settings.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
				settings.setLocationRelativeTo(view);
				settings.setVisible(true);
			}
			else if(menuItem.getText().equals("Help"))
			{
				// Show Help Window 
				HelpUI help = new HelpUI(view);
				help.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
				help.setLocationRelativeTo(view);
				help.setVisible(true);
			}
			else if(menuItem.getText().equals("About amoxcalli"))
			{
				// Show About amoxcalli Window
				AboutUI about = new AboutUI(view);
				about.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
				about.setLocationRelativeTo(view);
				about.setVisible(true);
			}
		}
		
	}
	
}

